package com.shop.cereshop.app.service.online.impl;

import com.alibaba.fastjson.JSON;
import com.shop.cereshop.app.service.online.OnlineUserService;
import com.shop.cereshop.commons.config.SecurityProperties;
import com.shop.cereshop.commons.constant.RedisConstants;
import com.shop.cereshop.commons.domain.buyer.CereBuyerUser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class OnlineUserServiceImpl implements OnlineUserService {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private SecurityProperties securityProperties;
    
    // 更新间隔时间（毫秒），避免频繁更新Redis
    private static final long UPDATE_INTERVAL = 60 * 1000; // 1分钟

    @Override
    public void userOnline(CereBuyerUser user, String token) {
        try {
            // 确保用户对象不为null
            if (user == null || user.getBuyerUserId() == null) {
                log.warn("用户对象或用户ID为空，跳过在线用户记录");
                return;
            }
            
            Long userId = user.getBuyerUserId();
            long currentTime = System.currentTimeMillis();
            
            // 获取token有效期，设置默认值
            long tokenValidity = securityProperties.getTokenValidityInSeconds();
            if (tokenValidity <= 0) {
                tokenValidity = 86400L; // 默认24小时
                log.warn("Token有效期无效，使用默认值: {}", tokenValidity);
            }
            
            // 计算过期时间
            long expireTime = currentTime + tokenValidity * 1000;

            // 记录调试信息
            log.debug("记录用户在线状态 - 用户ID: {}, 过期时间: {}", userId, expireTime);

            // 使用Lua脚本保证原子性操作
            String script =
                    "redis.call('ZADD', KEYS[1], ARGV[1], ARGV[2])\n" +
                            "redis.call('HSET', KEYS[2], ARGV[2], ARGV[3])\n" +
                            "redis.call('EXPIRE', KEYS[2], ARGV[4])\n" +
                            "return 1";

            // 明确指定参数类型，避免自动转换问题
            List<String> keys = Arrays.asList(
                    RedisConstants.ONLINE_USER_KEY,
                    RedisConstants.USER_INFO_PREFIX
            );

            List<Object> args = Arrays.asList(
                    expireTime,
                    userId,
                    user,
                    tokenValidity
            );

            redisTemplate.execute(
                    new DefaultRedisScript<>(script, Long.class),
                    keys,
                    args.toArray()
            );
        } catch (Exception e) {
            log.error("记录用户在线状态失败，用户信息: {}", user, e);
            // 不抛出异常，避免影响主业务流程
        }
    }
}
